import cv2
import numpy as np
import base64
from io import BytesIO
from PIL import Image
from PIL import ImageFile

# 设置最大像素限制为8000万像素
ImageFile.MAX_IMAGE_PIXELS = 64000000


def pngToJpg(imagePath, newPath):
    # 设置最大像素限制为8000万像素
    # ImageFile.MAX_IMAGE_PIXELS = 64000000

    im = Image.open(imagePath)
    im = im.convert('RGB')
    im.save(newPath, quality=98)


def webpToJpg(imagePath, newPath):
    img = Image.open(imagePath)
    # 将图片转换为RGB模式，因为JPG不支持透明度
    img = img.convert('RGB')

    # 保存为JPG格式
    img.save(newPath, 'JPEG')


def base64_to_file(imageData, imagePath):
    img = base64.b64decode(imageData)
    file = open(imagePath, 'wb')
    file.write(img)
    file.close()


def base64_to_numpy(image_base64):
    # 计算需要添加的等号数
    # image_bytes = base64.b64decode(image_base64)
    # image_np = np.frombuffer(image_bytes, dtype=np.uint8)
    # image_np2 = cv2.imdecode(image_np, cv2.IMREAD_COLOR)

    # 将base64数据解码为二进制数据
    binary_data = base64.b64decode(image_base64)
    # 将二进制数据转换为PIL Image对象
    image = Image.open(BytesIO(binary_data))
    # image = fix_color(image)
    # 将PIL Image对象转换为NumPy数组
    array = np.array(image)
    # 解决颜色变化的问题
    if image.mode == 'RGB' or image.mode == 'RGBA':
        # 如果通道顺序不是RGB，则将其翻转为RGB
        array = BGR_to_RGB(array)

    return array


def numpy_to_base64(image):
    img_base64 = base64.b64encode(image.tobytes()).decode('utf-8')
    return img_base64


def numpy_to_pil(array):
    # 将NumPy数组转换为PIL格式的图像
    pil_image = Image.fromarray(array)
    # 解决颜色变化的问题
    if pil_image.mode == 'RGBA':
        # 如果通道顺序是RGBA，则将其转换为RGB
        pil_image = pil_image.convert('RGB')
    elif pil_image.mode == 'RGB':
        # 如果通道顺序不是RGB，则将其翻转为RGB
        array = np.flip(array, axis=-1)
        pil_image = Image.fromarray(array)

    # 显示PIL格式的图像
    # pil_image.show()
    return pil_image


def jointImg(imgDataList, savePath):
    imgList = []
    for image_data in imgDataList:
        img = base64_to_numpy(image_data)

        # img = cv2.imread(image_string)
        imgList.append(img)

    if len(imgList) == 0:
        return
    maxWidth = 0
    h, w = imgList[0].shape[:2]
    if len(imgList) >= 2:
        maxWidth = w * 2
    else:
        maxWidth = w

    # s计算最大高度
    maxHeight = 0
    if len(imgList) >= 3:
        maxHeight = h * 2
    else:
        maxHeight = h

    # 创建一个新的空白图像，宽度为两张图片宽度的两倍，高度为两张图片高度的两倍
    new_img = np.zeros((maxHeight, maxWidth, 3), dtype=np.uint8)

    # # 将四张图片复制到新图像的对应位置
    if len(imgList) >= 1:
        new_img[:h, :w] = imgList[0]
    if len(imgList) >= 2:
        new_img[:h, w:] = imgList[1]
    if len(imgList) >= 3:
        new_img[h:, :w] = imgList[2]
    if len(imgList) >= 4:
        new_img[h:, w:] = imgList[3]

    # # 显示拼接后的图片
    # cv2.imshow("Stitched Image", new_img)
    # cv2.waitKey(0)
    # cv2.destroyAllWindows()
    cv2.imwrite(savePath, new_img)


def pil_base64(image):
    img_buffer = BytesIO()
    image = image.convert("RGBA")
    image.save(img_buffer, format='PNG')
    byte_data = img_buffer.getvalue()
    base64_str = base64.b64encode(byte_data)
    base64_str = str(base64_str, 'utf-8')
    return base64_str


def base64_pil(base64_str):
    image = base64.b64decode(base64_str)
    image = BytesIO(image)
    image = Image.open(image)
    return image


def pil_base64_prefix(image):
    """转换成base64 并且带base64的字符串头信息"""
    print("mode", image.mode)
    if image.mode == 'RGBA':
        return 'data:image/png;base64,' + pil_base64(image)
    else:
        # 转换成RGBA
        rgba_image = image.convert("RGBA")
        return 'data:image/png;base64,' + pil_base64(rgba_image)


def BGR_to_RGB(cvimg):
    pilimg = cvimg.copy()
    pilimg[:, :, 0] = cvimg[:, :, 2]
    pilimg[:, :, 2] = cvimg[:, :, 0]
    return pilimg


def cropAndResizeImg(img, width, height, resize=False):
    """裁剪和缩放图片,默认为中心裁剪，模仿网页的图片裁剪方式
    img pil的图片对象"""
    w = img.size[0]
    h = img.size[1]
    imgRatio = w / h
    ratio = (width / height)

    cropW = width
    cropH = height
    if width > height:  # 横图
        if ratio > imgRatio:
            cropW = w
            cropH = cropW / ratio
        else:
            cropH = h
            cropW = cropH * ratio
    else:
        # 竖图
        if ratio > imgRatio:
            cropW = w
            cropH = cropW / ratio
        else:
            cropH = h
            cropW = cropH * ratio

    # print("裁剪分辨率", cropW, cropH)

    # 计算开始裁剪的坐标
    startW = 0
    startH = 0
    if cropH < h:
        startH = (h - cropH) / 2
    else:
        startH = 0

    if cropW < w:
        startW = (w - cropW) / 2
    else:
        startW = 0

    # print(startW, startH)

    img = img.crop((startW, startH, cropW + startW, cropH + startH))

    # 裁剪为需要的分辨率大小
    if resize:
        img = img.resize((width, height), Image.LANCZOS)  # resize image with high-quality

    return img


def replace_black_with_mask(img):
    """转换成黑色背景白色蒙版的蒙版图"""
    # Convert the image to RGBA mode (if not already)
    img = img.convert("RGBA")
    w = img.size[0]
    h = img.size[1]
    data = img.getdata()

    new_data = []
    for item in data:
        # Replace black pixels (RGB value of (0, 0, 0)) with white (RGB value of (255, 255, 255))
        r = item[0]
        g = item[1]
        b = item[2]
        a = item[3]
        # print(r, g, b, a)
        if r == 0 and g == 0 and b == 0:
            new_data.append((255, 255, 255, a))

    img.putdata(new_data)

    # 创建黑色背景图
    # bgimg = Image.new("RGBA", (w, h), "black")
    bgimg = Image.new("RGBA", (w, h), (0, 0, 0, 0))
    bgimg.paste(img, (0, 0), mask=img)

    return bgimg


def invoke(imgList, savePath):
    jointImg(imgList)

# if __name__ == '__main__':
# imgList = [
#     r"N:\trainData\trans\NSFW\24.jpg",
#     r"N:\trainData\trans\NSFW\24.jpg",
#     r"N:\trainData\trans\NSFW\24.jpg",
#     r"N:\trainData\trans\NSFW\24.jpg",
# ]

##需要转成basses64
# jointImg(imgList, r"N:\trainData\trans\NSFW\test.jpg", )
